#include "Rtp.h"

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>


#include <iostream>
using namespace std;

CRtp::CRtp()
{
  m_sess = rtp_session_new(RTP_SESSION_SENDRECV);
  rtp_session_set_scheduling_mode(m_sess, false);
  rtp_session_set_blocking_mode(m_sess, false);
  user_ts = 0;

/*  rtp_profile_clear_all(&m_sprofile);
  rtp_profile_set_payload(&m_sprofile,0,&payload_type_pcmu8000);
  rtp_profile_set_payload(&m_sprofile,1,&payload_type_lpc1016);
  rtp_profile_set_payload(&m_sprofile,3,&payload_type_gsm);
  rtp_profile_set_payload(&m_sprofile,7,&payload_type_lpc);
  rtp_profile_set_payload(&m_sprofile,4,&payload_type_g7231);
  rtp_profile_set_payload(&m_sprofile,8,&payload_type_pcma8000);
  rtp_profile_set_payload(&m_sprofile,10,&payload_type_l16_stereo);
  rtp_profile_set_payload(&m_sprofile,11,&payload_type_l16_mono);
  rtp_profile_set_payload(&m_sprofile,18,&payload_type_g729);
  rtp_profile_set_payload(&m_sprofile,31,&payload_type_h261);
  rtp_profile_set_payload(&m_sprofile,32,&payload_type_mpv);
  rtp_profile_set_payload(&m_sprofile,34,&payload_type_h263);
  rtp_profile_set_payload(&m_sprofile,96,&payload_type_speex_wb);

  rtp_profile_clear_all(&m_rprofile);
  rtp_profile_set_payload(&m_rprofile,96,&payload_type_speex_wb);

  rtp_session_set_recv_profile(m_sess, &m_rprofile);
  rtp_session_set_send_profile(m_sess, &m_sprofile);*/
}

CRtp::~CRtp()
{
  rtp_session_destroy(m_sess);
}

uint16_t CRtp::GetPortBase() const
{
  return m_iPortBase;
}

void CRtp::SetFd()
{
  FD_SET(rtp_session_get_rtp_socket(m_sess), m_fdsRead);
  FD_SET(rtp_session_get_rtcp_socket(m_sess), m_fdsRead);
}

bool CRtp::Connect(std::string strDestIP, int iDestPort)
{
  if(rtp_session_set_remote_addr(m_sess, strDestIP.c_str(), iDestPort))
    return false;
  rtp_session_set_connected_mode(m_sess, true);
  return true;
}

void CRtp::Disconnect()
{
  rtp_session_bye(m_sess, "necum");
  rtp_session_set_connected_mode(m_sess, false);
  rtp_session_flush_sockets(m_sess);  
}

bool CRtp::BindPort(int iPortBase)
{
  if(rtp_session_set_local_addr(m_sess, "0.0.0.0", iPortBase) == 0) {
    m_iPortBase = iPortBase;
    return true;
  }
  return false;
}

int CRtp::SendPacket(const std::string &strContent, unsigned int timestamp)
{
  return rtp_session_send_with_ts(m_sess, (uint8_t *)strContent.c_str(), strContent.size(), timestamp);
}

int CRtp::SendPacket(const char *data, size_t size, unsigned int timestamp)
{
  return rtp_session_send_with_ts(m_sess, (uint8_t *)data, size, timestamp);
}

bool CRtp::ReadPacket(std::string &strContent, unsigned int timestamp)
{
  if(!FD_ISSET(rtp_session_get_rtp_socket(m_sess), m_fdsRead)) {
    return false;
  }
  mblk_t *packet;
  packet = rtp_session_recvm_with_ts(m_sess, user_ts);
  user_ts += timestamp;
  if(packet != NULL)
  {
    //rtp_get_payload(packet,&packet->b_rptr);
   // strContent = string((char *)packet->b_rptr, packet->b_wptr - packet->b_rptr);
    try
    {
        strContent = string((char *)packet->b_rptr, packet->b_wptr - packet->b_rptr);
        //strContent = string((char *)packet->b_rptr, timestamp);
        strContent = strContent.substr(12,strContent.size()-12);
    }
    catch (exception e)
    {
        return false;
    }
 	  cout << "new packet arrived. size: " << strContent.size() << endl;


    freemsg(packet);
    return true;
  }
  return false;
}

bool CRtp::SetPayloadType(bool mark, unsigned char type, unsigned int inc)
{
  return (rtp_session_set_payload_type(m_sess, type) == 0);  
}

bool CRtp::SetSendPayloadType(unsigned char type)
{
  return (rtp_session_set_send_payload_type(m_sess, type) == 0);  
}

bool CRtp::SetRecvPayloadType(unsigned char type)
{
  return (rtp_session_set_recv_payload_type(m_sess, type) == 0);  
}

